<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace Hyperfx\Framework\Logger;

use Hyperf\Context\Context;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Logger\Logger;
use Hyperf\Utils\ApplicationContext;
use OpenTracing\Span;
use function Zipkin\Propagation\Id\generateNextId;
use Hyperf\Logger\LoggerFactory;

class Logx
{
    public static function get(string $name = ''): Logger {
        if (empty($name)) {
            $name = ApplicationContext::getContainer()->get(ConfigInterface::class)->get('app_name');
        }
        return ApplicationContext::getContainer()->get(LoggerFactory::class)->get($name)->pushProcessor(function ($record) {
            if ($record['level'] > Logger::DEBUG) {
                $callStack        = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 12);
                foreach ($callStack as $trace) {
                    if (isset($trace['class'])
                        && isset($trace['function'])
                        && $trace['class'] == \Monolog\Logger::class
                        && in_array(
                            $trace['function'],
                            [
                                'log',
                                'info',
                                'notice',
                                'warning',
                                'error',
                                'emergency',
                                'alert',
                                'critical',
                                'warn',
                                'err',
                                'crit',
                                'emerg',
                            ]
                        )
                    ) {
                        $record['extra']['file'] = sprintf('%s:%u', basename($trace['file']), $trace['line']);
                        break;
                    }
                }
            }
            $record['extra']['trace_id'] = self::getTraceId();
            return $record;
        });
    }

    public static function getTraceId(): string {
        $root = Context::get('tracer.root');
        if ($root instanceof Span) {
            return $root->getContext()->getContext()->getTraceId();
        }
        return generateNextId();
    }

    public static function isDebugLevel(): bool {
        $logDevel = ApplicationContext::getContainer()->get(ConfigInterface::class)->get('logger.default.handler.constructor.level', '');
        return $logDevel == Logger::DEBUG || 0 == strcmp($logDevel, 'DEBUG');
    }
}
